package rpc_1.Server;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import rpc_1.Impl.HelloServiceImpl;
import rpc_1.Service.RpcException;
import rpc_1.object.ResponseCode;
import rpc_1.object.RpcRequest;
import rpc_1.object.RpcResponse;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

//分离各个功能，解耦

//因为接口变了，这里懒得改了
public class RpcServer_2 {
    /*
    private static final Logger logger= LoggerFactory.getLogger(RpcServer_2.class);
    private final ExecutorService threadPool;
    //注册过的服务信息
    private final ServiceRegistry serviceRegistry;
    private RequestHandler requestHandler=new RequestHandler();

    public RpcServer_2(ServiceRegistry sr){
        this.serviceRegistry=sr;
        threadPool= Executors.newFixedThreadPool(2);

    }
    //负责启动serversocket，对于成功建立的socket连接，通过线程池，交给requestHandlerThread去做
    public void start(int port){
        try {
            ServerSocket serverSocket = new ServerSocket(port);
            logger.info("server starting---");
            Socket socket;
            while ((socket=serverSocket.accept())!=null){
                logger.info("{}:{} connect",socket.getInetAddress(),socket.getPort());
                threadPool.execute(new RequestHandlerThread(socket,requestHandler,serviceRegistry));
            }
        } catch (IOException e) {
            e.printStackTrace();
            logger.error("error!");
        }
    }

    static class RequestHandlerThread implements Runnable{
        private static final Logger logger=LoggerFactory.getLogger(RequestHandler.class);
        private Socket socket;
        private RequestHandler requestHandler;
        private ServiceRegistry serviceRegistry;

        public RequestHandlerThread(Socket socket, RequestHandler requestHandler, ServiceRegistry serviceRegistry) {
            this.socket=socket;
            this.requestHandler=requestHandler;
            this.serviceRegistry=serviceRegistry;
        }

        @Override
        public void run() {
            try {
                //读取客户端传来的rpcRequest
                ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
                ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
                RpcRequest rpcRequest =(RpcRequest) objectInputStream.readObject();
                String interfaceName = rpcRequest.getInterfaceName();
                Object service = serviceRegistry.getService(interfaceName);
                //把实现真正函数调用的功能交给requestHandler去做，并且接收结果
                Object result= requestHandler.handle(rpcRequest, service);
                //设置返回信息，返回结果
                ResponseCode responseCode = new ResponseCode();
                if (result!=null){
                    responseCode.setSUCCESS_CODE(1);
                    responseCode.setMessage("success!");
                }else {
                    responseCode.setSUCCESS_CODE(0);
                    responseCode.setMessage("rpc fail!");
                }
                objectOutputStream.writeObject(RpcResponse.success(result, responseCode));
                objectOutputStream.flush();
            } catch (IOException | ClassNotFoundException | RpcException e) {
                e.printStackTrace();
            }
        }
    }

    static class RequestHandler{
        private static final Logger logger=LoggerFactory.getLogger(RequestHandler.class);

        public Object handle(RpcRequest rpcRequest, Object service) {
            Object result=null;
            try{
                result=invokeTargetService(rpcRequest,service);
                logger.info("success!");
            }catch (Exception E){
                logger.error("error when handling");
                return result;
            }
            return result;

        }

        public Object invokeTargetService(RpcRequest rpcRequest,Object service) throws InvocationTargetException, IllegalAccessException {
            Method method;
            try {
                //这里需要注意下，getMethod需要传入方法信息和方法参数类型
                method = service.getClass().getMethod(rpcRequest.getMethodName(),rpcRequest.getParamTypes());
            }catch (Exception E){
                logger.error("error when invoking!");
                return null;
            }
            return method.invoke(service,rpcRequest.getParameters());
        }


    }

    //test
    public static void main(String[] args) throws RpcException {
        ServiceRegistry serviceRegistry=new DefaultServiceRegistry();
        serviceRegistry.register(new HelloServiceImpl());
        RpcServer_2 rpcServer=new RpcServer_2(serviceRegistry);
        rpcServer.start(8825);
    }*/

 }
